package com.atguigu.daijia.driver.service.impl;

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import com.atguigu.daijia.common.constant.SystemConstant;
import com.atguigu.daijia.common.execption.GuiguException;
import com.atguigu.daijia.common.result.ResultCodeEnum;
import com.atguigu.daijia.common.util.DateUtils;
import com.atguigu.daijia.driver.config.TencentCloudProperties;
import com.atguigu.daijia.driver.mapper.*;
import com.atguigu.daijia.driver.service.CosService;
import com.atguigu.daijia.driver.service.DriverInfoService;
import com.atguigu.daijia.model.entity.driver.*;
import com.atguigu.daijia.model.form.driver.DriverFaceModelForm;
import com.atguigu.daijia.model.form.driver.UpdateDriverAuthInfoForm;
import com.atguigu.daijia.model.vo.driver.DriverAuthInfoVo;
import com.atguigu.daijia.model.vo.driver.DriverInfoVo;
import com.atguigu.daijia.model.vo.driver.DriverLoginVo;
import com.atguigu.daijia.model.vo.driver.DriverSetVo;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tencentcloudapi.common.AbstractModel;
import com.tencentcloudapi.common.exception.TencentCloudSDKException;
import com.tencentcloudapi.iai.v20200303.IaiClient;
import com.tencentcloudapi.iai.v20200303.models.*;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.error.WxErrorException;
import org.joda.time.DateTime;
import org.springframework.beans.BeanUtils;
import org.springframework.util.StringUtils;
import org.springframework.stereotype.Service;
import java.math.BigDecimal;
import java.util.Date;

@Slf4j
@Service("driverInfoService")
@SuppressWarnings({"unchecked", "rawtypes"})
public class DriverInfoServiceImpl extends ServiceImpl<DriverInfoMapper, DriverInfo> implements DriverInfoService {
    @Resource
    private WxMaService wxMaService;
    @Resource
    private CosService cosService;
    @Resource
    private DriverSetMapper driverSetMapper;
    @Resource
    private DriverInfoMapper driverInfoMapper;
    @Resource
    private DriverAccountMapper driverAccountMapper;

    @Resource
    private DriverLoginLogMapper driverLoginLogMapper;

    @Resource
    private DriverFaceRecognitionMapper faceRecognitionMapper;

    @Resource
    private IaiClient iaiClient;

    @Resource
    private TencentCloudProperties tencentCloudProperties;



    /*
     * @param code
     * @==============History===============<br/>;
     * @Description //   小程序授权登录
     * @Date 2024/8/1
     * @Author < a href="15991488967@163.com">chen</ a>;
     */
    @Override
    public Long login(String code) {
        //根据code + 小程序id + 秘钥请求微信接口，返回openid
        WxMaJscode2SessionResult sessionInfo =null;
        String openid = null;
        Long driverId = null;
        try {
            sessionInfo = wxMaService.getUserService().getSessionInfo(code);
            openid = sessionInfo.getOpenid();
        } catch (WxErrorException e) {
            throw new RuntimeException(e);
        }
        // 根据openid查询数据库，如果存在则返回id，如果不存在则保存后返回id
        LambdaQueryWrapper<DriverInfo>  queryWrapper = Wrappers.lambdaQuery(DriverInfo.class);
        queryWrapper.eq(DriverInfo::getWxOpenId,openid);
        DriverInfo driverInfo = driverInfoMapper.selectOne(queryWrapper);

        if(driverInfo == null){
            driverInfo = new DriverInfo();
            // 设置司机的基本信息
            driverInfo.setNickname(String.valueOf(System.currentTimeMillis()));
            driverInfo.setAvatarUrl("https://oss.aliyuncs.com/aliyun_id_photo_bucket/default_handsome.jpg");
            driverInfo.setWxOpenId(openid);
            // 0：未认证 1：审核中 2：认证成功
            driverInfo.setAuthStatus(0);
            driverInfoMapper.insert(driverInfo);

            // 初始化司机设置
            DriverSet driverSet = new DriverSet();
            driverSet.setDriverId(driverInfo.getId());
            driverSet.setOrderDistance(new BigDecimal(0));//0:无限制
            driverSet.setAcceptDistance(new BigDecimal(SystemConstant.ACCEPT_DISTANCE));//默认接单范围：5公里
            driverSet.setIsAutoAccept(0);//0：否 1：是
            driverSetMapper.insert(driverSet);

            //初始化司机账户信息
            DriverAccount driverAccount = new DriverAccount();
            driverAccount.setDriverId(driverInfo.getId());
            driverAccountMapper.insert(driverAccount);
        }
        // 记录司机登录信息
        DriverLoginLog driverLoginLog = new DriverLoginLog();
        driverLoginLog.setDriverId(driverInfo.getId());
        driverLoginLog.setMsg("小程序登录");
        driverLoginLogMapper.insert(driverLoginLog);

        driverId = driverInfo.getId();
        return driverId;
    }


    /*
     * @param driverId
     * @==============History===============<br/>;
     * @Description //   获取司机登录信息
     * @Date 2024/8/1
     * @Author < a href="15991488967@163.com">chen</ a>;
     */
    @Override
    public DriverLoginVo getDriverInfo(Long driverId) {

        DriverInfo driverInfo = driverInfoMapper.selectById(driverId);

        DriverLoginVo driverLoginVo = new DriverLoginVo();
        BeanUtils.copyProperties(driverInfo,driverLoginVo);

        // 是否建档人脸识别
        String faceModelId = driverInfo.getFaceModelId();
        boolean isArchiveFace = StringUtils.hasText(faceModelId);
        driverLoginVo.setIsArchiveFace(isArchiveFace);

        return driverLoginVo;
    }

    /*
     * @param driverId
     * @==============History===============<br/>;
     * @Description //   获取司机认证信息
     * @Date 2024/8/7
     * @Author < a href="15991488967@163.com">chen</ a>;
     */
    @Override
    public DriverAuthInfoVo getDriverAuthInfo(Long driverId) {
        DriverInfo driverInfo = driverInfoMapper.selectById(driverId);
        DriverAuthInfoVo driverAuthInfoVo = new DriverAuthInfoVo();
        BeanUtils.copyProperties(driverInfo,driverAuthInfoVo);

        driverAuthInfoVo.setIdcardBackShowUrl(cosService.getImageUrl(driverAuthInfoVo.getIdcardBackUrl()));
        driverAuthInfoVo.setIdcardFrontShowUrl(cosService.getImageUrl(driverAuthInfoVo.getIdcardFrontUrl()));
        driverAuthInfoVo.setIdcardHandShowUrl(cosService.getImageUrl(driverAuthInfoVo.getIdcardHandUrl()));
        driverAuthInfoVo.setDriverLicenseFrontShowUrl(cosService.getImageUrl(driverAuthInfoVo.getDriverLicenseFrontUrl()));
        driverAuthInfoVo.setDriverLicenseBackShowUrl(cosService.getImageUrl(driverAuthInfoVo.getDriverLicenseBackUrl()));
        driverAuthInfoVo.setDriverLicenseHandShowUrl(cosService.getImageUrl(driverAuthInfoVo.getDriverLicenseHandUrl()));
        return driverAuthInfoVo;
    }

    
    /*
     * @param updateDriverAuthInfoForm 
     * @==============History===============<br/>;
     * @Description //   更新司机的认证信息
     * @Date 2024/8/8
     * @Author < a href="15991488967@163.com">chen</ a>;
     */
    @Override
    public Boolean updateDriverAuthInfo(UpdateDriverAuthInfoForm updateDriverAuthInfoForm) {
        // 获取司机的id
        DriverInfo driverInfo = new DriverInfo();
        driverInfo.setId(updateDriverAuthInfoForm.getDriverId());
        BeanUtils.copyProperties(updateDriverAuthInfoForm,driverInfo);
        return updateById(driverInfo);
    }

    /*
     * @param driverFaceModelForm 
     * @==============History===============<br/>;
     * @Description //   创建司机人脸模型
     * @Date 2024/8/8
     * @Author < a href="15991488967@163.com">chen</ a>;
     */
    @Override
    public Boolean creatDriverFaceModel(DriverFaceModelForm driverFaceModelForm) {
        // 获取司机信息
        DriverInfo driverInfo = this.getById(driverFaceModelForm.getDriverId());
        try {
            // 实例化一个请求对象,每个接口都会对应一个request对象
            CreatePersonRequest req = new CreatePersonRequest();
            //设置相关值
            req.setGroupId(tencentCloudProperties.getPersionGroupId());
            //基本信息
            req.setPersonId(String.valueOf(driverInfo.getId()));
            req.setGender(Long.parseLong(driverInfo.getGender()));
            req.setQualityControl(4L);
            req.setUniquePersonControl(4L);
            req.setPersonName(driverInfo.getName());
            req.setImage(driverFaceModelForm.getImageBase64());
            CreatePersonResponse resp = iaiClient.CreatePerson(req);
            // 输出json格式的字符串回包
            log.info("人脸模型创建成功,{}",AbstractModel.toJsonString(resp));
            String faceId = resp.getFaceId();
            if(StringUtils.hasText(faceId)) {
                driverInfo.setFaceModelId(faceId);
                driverInfoMapper.updateById(driverInfo);
            }
        } catch (TencentCloudSDKException e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }

    /*
     * @param driverId 
     * @==============History===============<br/>;
     * @Description //   判断司机当日是否进行过人脸识别
     * @Date 2024/8/8
     * @Author < a href="15991488967@163.com">chen</ a>;
     */
    @Override
    public Boolean isFaceRecognition(Long driverId) {
        LambdaQueryWrapper<DriverFaceRecognition> wrapper = Wrappers.lambdaQuery(DriverFaceRecognition.class);
        wrapper.eq(DriverFaceRecognition::getDriverId,driverId);
        wrapper.eq(DriverFaceRecognition::getFaceDate,DateUtils.getDate());
        Long count = faceRecognitionMapper.selectCount(wrapper);
        return count > 0;
    }

    /*
     * @param driverFaceModelForm 
     * @==============History===============<br/>;
     * @Description //   验证司机人脸
     * @Date 2024/8/8
     * @Author < a href="15991488967@163.com">chen</ a>;
     */
    @Override
    public Boolean verifyDriverFace(DriverFaceModelForm driverFaceModelForm) {
        try {
            VerifyFaceRequest req = new VerifyFaceRequest();
            //设置相关参数
            req.setImage(driverFaceModelForm.getImageBase64());
            req.setPersonId(String.valueOf(driverFaceModelForm.getDriverId()));
            // 返回的resp是一个VerifyFaceResponse的实例，与请求对象对应
            VerifyFaceResponse resp = iaiClient.VerifyFace(req);
            // 输出json格式的字符串回包
            log.info("--->>,{}",AbstractModel.toJsonString(resp));
            if(resp.getIsMatch()) {
                // 如果照片比对成功，静态活体检测
                Boolean isSuccess = this.detectLiveFace(driverFaceModelForm.getImageBase64());
                if(isSuccess) {
                    // 如果静态活体检测通过，添加数据到认证表里面
                    DriverFaceRecognition driverFaceRecognition = new DriverFaceRecognition();
                    driverFaceRecognition.setDriverId(driverFaceModelForm.getDriverId());
                    driverFaceRecognition.setFaceDate(new Date());
                    faceRecognitionMapper.insert(driverFaceRecognition);
                    return true;
                }
            }
        } catch (TencentCloudSDKException e) {
            e.printStackTrace();
        }
        throw new GuiguException(ResultCodeEnum.DATA_ERROR);
    }


    /*
     * @param driverId
     * @==============History===============<br/>;
     * @Description //   获取司机设置信息
     * @Date 2024/8/8
     * @Author < a href="15991488967@163.com">chen</ a>;
     */
    @Override
    public DriverSetVo getDriverSet(Long driverId) {
        DriverSetVo driverSetVo = new DriverSetVo();
        LambdaQueryWrapper<DriverSet> wrapper = Wrappers.lambdaQuery(DriverSet.class);
        wrapper.eq(DriverSet::getDriverId,driverId);
        DriverSet driverSet = driverSetMapper.selectOne(wrapper);
        BeanUtils.copyProperties(driverSet,driverSetVo);
        return driverSetVo;
    }

    /*
     * @param driverId 
     * @==============History===============<br/>;
     * @Description //   获取司机基本信息
     * @Date 2024/8/8
     * @Author < a href="15991488967@163.com">chen</ a>;
     */
    @Override
    public DriverInfoVo getDriverInfoOrder(Long driverId) {
        //司机id获取基本信息
        DriverInfo driverInfo = driverInfoMapper.selectById(driverId);
        //封装DriverInfoVo
        DriverInfoVo driverInfoVo = new DriverInfoVo();
        BeanUtils.copyProperties(driverInfo,driverInfoVo);
        //计算驾龄
        //获取当前年
        int currentYear = new DateTime().getYear();
        //获取驾驶证初次领证日期
        //driver_license_issue_date
        int firstYear = new DateTime(driverInfo.getDriverLicenseIssueDate()).getYear();
        int driverLicenseAge = currentYear - firstYear;
        driverInfoVo.setDriverLicenseAge(driverLicenseAge);
        return driverInfoVo;
    }

    /*
     * @param driverId   司机id
     * @param status     接单状态
     * @==============History===============<br/>
     * @Description //   更新司机接单状态
     * @Date 2024-8-26 20:55
     * @Author < a href="15991488967@163.com">chen</ a>
     * @return java.lang.Boolean
     */
    @Override
    public Boolean updateServiceStatus(Long driverId, Integer status) {
        LambdaUpdateWrapper<DriverSet> wrapper = Wrappers.lambdaUpdate();
        wrapper.eq(DriverSet::getDriverId,driverId);
        DriverSet driverSet = new DriverSet();
        driverSet.setServiceStatus(status);
        int update = driverSetMapper.update(driverSet, wrapper);
        return update > 0;
    }

    /*
     * @param imageBase64 
     * @==============History===============<br/>;
     * @Description //   人体静态活体检测
     * @Date 2024/8/8
     * @Author < a href="15991488967@163.com">chen</ a>;
     */
    private Boolean detectLiveFace(String imageBase64) {
        try {
            DetectLiveFaceRequest req = new DetectLiveFaceRequest();
            req.setImage(imageBase64);
            // 返回的resp是一个DetectLiveFaceResponse的实例，与请求对象对应
            DetectLiveFaceResponse resp = iaiClient.DetectLiveFace(req);
            // 输出json格式的字符串回包
            log.info("人体静态活体检测,{}",AbstractModel.toJsonString(resp));
            if(resp.getIsLiveness()) {
                return true;
            }
        } catch (TencentCloudSDKException e) {
            e.printStackTrace();
        }
        return false;
    }
}